package zslice

import (
	"math/rand"
	"venus/util/ztype"
)

// Contains 判断切片是否包含某元素
func Contains[T comparable](list []T, value T) bool {
	for _, v := range list {
		if v == value {
			return true
		}
	}
	return false
}

// RandomOne 随机一个元素
func RandomOne[T any](list []T) T {
	if len(list) <= 0 {
		return *new(T)
	}
	return list[rand.Intn(len(list))]
}

// Remove 切片删除一个元素
func Remove[T comparable](list []T, item T) []T {
	for i := 0; i < len(list); i++ {
		if item == list[i] {
			list = append(list[:i], list[i+1:]...)
			i = i - 1
		}
	}
	return list
}

// RemoveList 切片删除多个元素
func RemoveList[T comparable](list []T, items []T) []T {
	dMap := make(map[T]bool)
	for _, s := range items {
		dMap[s] = true
	}

	for i := 0; i < len(list); i++ {
		if _, ok := dMap[list[i]]; ok {
			list = append(list[:i], list[i+1:]...)
			i = i - 1
		}
	}
	return list
}

// Sum 求和
func Sum[T ztype.UtNumber](list []T) T {
	var result T = 0
	for _, v := range list {
		result += v
	}
	return result
}

// Min 最小值
func Min[T ztype.UtNumber](list []T) T {
	var result T = 0
	for _, v := range list {
		if v < result {
			result = v
		}
	}
	return result
}

// Max 最大值
func Max[T ztype.UtNumber](list []T) T {
	var result T = 0
	for _, v := range list {
		if v > result {
			result = v
		}
	}
	return result
}

// Any 其中有一个元素符合就返回true
func Any[T ztype.UtNumber](list []T, value T) bool {
	for _, v := range list {
		if v == value {
			return true
		}
	}
	return false
}

// AnyEquals 其中有一个元素符合就返回true
func AnyEquals[T ztype.EqualAble](list []T, value T) bool {
	for _, v := range list {
		if v.Equals(value) {
			return true
		}
	}
	return false
}

// AnyBy 其中有一个元素符合就返回true
func AnyBy[T any](list []T, value T, equals func(v1 T, v2 T) bool) bool {
	for _, v := range list {
		if equals(v, value) {
			return true
		}
	}
	return false
}

// All 所有元素符合就返回true
func All[T ztype.UtNumber](list []T, value T) bool {
	for _, v := range list {
		if v != value {
			return false
		}
	}
	return true
}

// AllEquals 所有元素符合就返回true
func AllEquals[T ztype.EqualAble](list []T, value T) bool {
	for _, v := range list {
		if !v.Equals(value) {
			return false
		}
	}
	return true
}

// AllBy 所有元素符合就返回true
func AllBy[T any](list []T, value T, equals func(v1 T, v2 T) bool) bool {
	for _, v := range list {
		if !equals(v, value) {
			return false
		}
	}
	return true
}

// Filter 过滤
func Filter[T comparable](list []T, value T) []T {
	result := make([]T, 0)
	for _, v := range list {
		if v == value {
			result = append(result, v)
		}
	}
	return result
}

// FilterEquals 过滤
func FilterEquals[T ztype.EqualAble](list []T, value T) []T {
	result := make([]T, 0)
	for _, v := range list {
		if v.Equals(value) {
			result = append(result, v)
		}
	}
	return result
}

// FilterBy 过滤
func FilterBy[T any](list []T, value T, equals func(v1 T, v2 T) bool) []T {
	result := make([]T, 0)
	for _, v := range list {
		if equals(v, value) {
			result = append(result, v)
		}
	}
	return result
}

// Shuffle 打乱
func Shuffle[T any](list []T) {
	for i := len(list) - 1; i > 0; i-- {
		j := rand.Intn(i + 1)
		list[i], list[j] = list[j], list[i]
	}
}
